package com.wetao.lib_common.view.graffiti;

import android.animation.ValueAnimator;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.RectF;
import android.view.MotionEvent;

import com.wetao.lib_common.utils.LogUtils;

import java.util.List;

public class GraffitiOnTouchGestureListener extends TouchGestureDetector.OnTouchGestureListener {
    //触摸的方式
    public static final int TOUCH_TYPE_ALL = 0;
    public static final int TOUCH_TYPE_FINGER = 1;
    public static final int TOUCH_TYPE_PEN = 2;
    private int mFingerId = -1;
    private int mPenId = -1;
    private int mTouchType = TOUCH_TYPE_ALL;

    private boolean mSupportScale = true; //是否支持放大缩小
    private boolean mSupportGraffiti = true; //是否支持涂鸦，默认支持
    private boolean mSupportTrans = false; //是否不涂鸦只垂直滑动，默认不支持

    // 触摸的相关信息
    private float mTouchX, mTouchY;
    private float mLastTouchX, mLastTouchY;
    private float mTouchDownX, mTouchDownY;

    // 缩放相关
    private Float mLastFocusX;
    private Float mLastFocusY;
    private float mTouchCentreX, mTouchCentreY;

    // 动画相关
    private ValueAnimator mScaleAnimator;
    private float mScaleAnimTransX, mScaleAnimTranY;
    private ValueAnimator mTranslateAnimator;
    private float mTransAnimOldY, mTransAnimY;

    private Path mCurrPath; // 当前手写的路径

    private static final float VALUE = 1f;

    private float pendingX, pendingY, pendingScale = 1;

    private GraffitiPath mCurrGraffitiPath;


    private GraffitiView mGraffitiView;
    private IGraffitiOnTouchGestureListener mListener;
    public interface IGraffitiOnTouchGestureListener{
        void onTest();
        void onCallScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);
    }
    public GraffitiOnTouchGestureListener(GraffitiView graffitiView, IGraffitiOnTouchGestureListener listener) {
        mGraffitiView = graffitiView;
        mListener = listener;
    }

    public void setTouchType(int type) {
        mTouchType = type;
    }

    public int getTouchType() {
        return mTouchType;
    }

    public void setSupportScale(boolean supportScale) {
        mSupportScale = supportScale;
    }

    public boolean isSupportScale() {
        return mSupportScale;
    }

    public void setSupportGraffiti(boolean supportGraffiti) {
        mSupportGraffiti = supportGraffiti;
    }

    public boolean isSupportGraffiti() {
        return mSupportGraffiti;
    }


    public void setSupportTrans(boolean supportTrans) {
        mSupportTrans = supportTrans;
    }

    public boolean isSupportTrans() {
        return mSupportTrans;
    }

    public void setGraffitiTranslationXY(float x, float y) {
        mGraffitiView.setGraffitiTranslation(x, y);
    }

    @Override
    public boolean onDown(MotionEvent e) {
        if(e.getPressure() >= 1) {
            mFingerId = e.getDeviceId();
        } else {
            mPenId = e.getDeviceId();
        }

        if(mTouchType == TOUCH_TYPE_FINGER) {
            if(e.getDeviceId() == mFingerId
            ) {
            } else {
                return true;
            }
        } else if (mTouchType == TOUCH_TYPE_PEN) {
            if(e.getDeviceId() == mPenId) {
            } else {
                return true;
            }
        }/* else {
            if(mPenId != -1 && e.getPressure() >= 1) {
                return true;
            }
        }*/

        if(!mSupportGraffiti) {
            return true;
        }
        //getDeviceId:2:揽阅平板手触摸，7:华为揽阅笔触摸
        //LogUtils.i("----笔onDown---getDeviceId:" + e.getDeviceId() + "---getPressure:" + e.getPressure() + "--x:" + e.getX() + "--y:" +e.getY() + "--rawx:" + e.getRawX() + "--rawy:" + e.getRawY());
        r_onDown(e.getX(), e.getY());
        return true;
    }

    public void r_onDown(float x, float y) {
        LogUtils.i("m3: r_onDown x:" + x + ", y:" + y);
        mTouchX = mTouchDownX = x;
        mTouchY = mTouchDownY = y;
    }

    @Override
    public void onUpOrCancel(MotionEvent e) {
        super.onUpOrCancel(e);
        LogUtils.i("m3: onUpOrCancel x:" + e.getX() + ", y:" + e.getY());
        if(!mSupportGraffiti) {
            return;
        }
    }

    /**
     * 开始滚动
     *
     * @param event
     */
    @Override
    public void onScrollBegin(MotionEvent event) {
        if(mTouchType == TOUCH_TYPE_FINGER) {
            if(event.getDeviceId() == mFingerId
            ) {
            } else {
                return;
            }
        } else if (mTouchType == TOUCH_TYPE_PEN) {
            if(event.getDeviceId() == mPenId) {
            } else {
                return;
            }
        }/* else {
            if(mPenId != -1 && event.getPressure() >= 1) {
                return;
            }
        }*/

        if(!mSupportGraffiti) {
            return;
        }

        //LogUtils.i("----笔onScrollBegin--- e->" + event);

        r_onScrollBegin(event.getX(), event.getY());
    }

    public void r_onScrollBegin(float x, float y) {
        LogUtils.i("m3: r_onScrollBegin x:" + x + ", y:" + y);
        mLastTouchX = mTouchX = x;
        mLastTouchY = mTouchY = y;

        // 初始化绘制
        mCurrPath = new Path();
        mCurrPath.moveTo(mGraffitiView.toX(mTouchX), mGraffitiView.toY(mTouchY));

        mCurrGraffitiPath = GraffitiPath.toPath(mGraffitiView, mCurrPath);

        if (mGraffitiView.isOptimizeDrawing()) {
            mGraffitiView.markItemToOptimizeDrawing(mCurrGraffitiPath);
        } else {
            mGraffitiView.addItem(mCurrGraffitiPath);
        }

        mGraffitiView.refresh();
    }

    @Override
    public void onScrollEnd(MotionEvent e) {
        int fingerId = mFingerId;
        int penId = mPenId;
        if(e.getPressure() >= 1) {
            mFingerId = -1;
        } else {
            mPenId = -1;
        }
        if(mTouchType == TOUCH_TYPE_FINGER) {
            if(e.getDeviceId() == fingerId
            ) {
            } else {
                return;
            }
        } else if (mTouchType == TOUCH_TYPE_PEN) {
            if(e.getDeviceId() == penId) {
            } else {
                return;
            }
        }/* else {
            if(penId != -1 && e.getPressure() >= 1) {
                return;
            }
        }*/


        if(!mSupportGraffiti) {
            return;
        }

        //LogUtils.i("----笔onScrollEnd--- e->" + e);

        r_onScrollEnd(e.getX(), e.getY());
    }

    public void r_onScrollEnd(float x, float y) {
        LogUtils.i("m3: r_onScrollEnd x:" + x + ", y:" + y);
        mLastTouchX = mTouchX;
        mLastTouchY = mTouchY;
        mTouchX = x;
        mTouchY = y;

        if (mCurrGraffitiPath != null) {
            if (mGraffitiView.isOptimizeDrawing()) {
                mGraffitiView.notifyItemFinishedDrawing(mCurrGraffitiPath);
            }
            mCurrGraffitiPath = null;
        }

        mGraffitiView.refresh();
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        if(mTouchType == TOUCH_TYPE_FINGER) {
            if(e1.getDeviceId() == mFingerId && e2.getDeviceId() == mFingerId
            ) {
            } else {
                return true;
            }
        } else if (mTouchType == TOUCH_TYPE_PEN) {
            if(e1.getDeviceId() == mPenId && e2.getDeviceId() == mPenId) {
            } else {
                return true;
            }
        }/* else {
            if(mPenId != -1 && (e1.getPressure() >= 1 || e2.getPressure() >= 1)) {
                return true;
            }
        }*/

        if(!mSupportGraffiti && mSupportTrans) {
            LogUtils.i("----笔->" + mGraffitiView.getGraffitiTranslationY()
                    + "->" + distanceY + "->" + mGraffitiView.getHeight()
                    + "->" + mGraffitiView.getWidth()+ "->" + mGraffitiView.getAllScale()
                    + "->" + mGraffitiView.getBitmapHeight()
                    + "->" + mGraffitiView.getBitmapHeight()*mGraffitiView.getAllScale());
            float tranY = mGraffitiView.getGraffitiTranslationY() - distanceY;
            if(mGraffitiView.getBitmapHeight()*mGraffitiView.getAllScale()<= mGraffitiView.getHeight()) {

            } else if(tranY > 0  && mGraffitiView.getGraffitiTranslationY() < 0) {
                mGraffitiView.setGraffitiTranslationY(0);
            } else if(tranY <=0) {
                if(mGraffitiView.getBitmapHeight()*mGraffitiView.getAllScale() + tranY > mGraffitiView.getHeight()) {
                    mGraffitiView.setGraffitiTranslationY(tranY);
                }
            }
        }

        if(mListener != null) {
            mListener.onCallScroll(e1, e2, distanceX, distanceY);
        }

        if(!mSupportGraffiti) {
            return true;
        }
        //LogUtils.i("----笔onScroll -- e1->" + e1 + "--e2->" + e2);

        r_onScroll(e2.getX(), e2.getY());
        return true;
    }

    public void r_onScroll(float x, float y) {
        LogUtils.i("m3: r_onScroll x:" + x + ", y:" + y);
        mLastTouchX = mTouchX;
        mLastTouchY = mTouchY;
        mTouchX = x;
        mTouchY = y;

        if(mCurrPath == null) {
            return;
        }

        mCurrPath.quadTo(
                mGraffitiView.toX(mLastTouchX),
                mGraffitiView.toY(mLastTouchY),
                mGraffitiView.toX((mTouchX + mLastTouchX) / 2),
                mGraffitiView.toY((mTouchY + mLastTouchY) / 2));
        if(mCurrGraffitiPath != null) {
            mCurrGraffitiPath.updatePath(mCurrPath);
        }

        mGraffitiView.refresh();

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        LogUtils.i("m3: onSingleTapUp x:" + e.getX() + ", y:" + e.getY());
        if(mTouchType == TOUCH_TYPE_FINGER) {
            if(e.getDeviceId() == mFingerId
            ) {
            } else {
                return true;
            }
        } else if (mTouchType == TOUCH_TYPE_PEN) {
            if(e.getDeviceId() == mPenId) {
            } else {
                return true;
            }
        }/* else {
            if(mPenId != -1 && e.getPressure() >= 1) {
                return true;
            }
        }*/

        if(!mSupportGraffiti) {
            return true;
        }

        //LogUtils.i("----笔onSingleTapUp");

        mLastTouchX = mTouchX;
        mLastTouchY = mTouchY;
        mTouchX = e.getX();
        mTouchY = e.getY();

        // 模拟一次滑动
        onScrollBegin(e);
        e.offsetLocation(VALUE, VALUE);
        onScroll(e, e, VALUE, VALUE);
        onScrollEnd(e);

        mGraffitiView.refresh();
        return true;
    }

    @Override
    public boolean onScaleBegin(ScaleGestureDetectorApi27 detector) {
        LogUtils.i("m3: onScaleBegin");
        mLastFocusX = null;
        mLastFocusY = null;
        return true;
    }

    @Override
    public boolean onScale(ScaleGestureDetectorApi27 detector) {
        LogUtils.i("m3: onScale");
        if(!mSupportScale) {
            return false;
        }
        // 屏幕上的焦点
        mTouchCentreX = detector.getFocusX();
        mTouchCentreY = detector.getFocusY();

        if (mLastFocusX != null && mLastFocusY != null) { // 焦点改变
            final float dx = mTouchCentreX - mLastFocusX;
            final float dy = mTouchCentreY - mLastFocusY;
            // 移动图片
            if (Math.abs(dx) > 1 || Math.abs(dy) > 1) {
                mGraffitiView.setGraffitiTranslationX(mGraffitiView.getGraffitiTranslationX() + dx + pendingX);
                mGraffitiView.setGraffitiTranslationY(mGraffitiView.getGraffitiTranslationY() + dy + pendingY);
                pendingX = pendingY = 0;
            } else {
                pendingX += dx;
                pendingY += dy;
            }
        }

        mLastFocusX = mTouchCentreX;
        mLastFocusY = mTouchCentreY;

        return true;
    }

    @Override
    public void onScaleEnd(ScaleGestureDetectorApi27 detector) {
        LogUtils.i("m3: onScaleEnd");
        if(!mSupportScale) {
            return;
        }


    }
}
